package com.blue.base.oauth.thirdpart.controller;

import com.blue.base.common.bean.resp.JsonResult;
import com.blue.base.common.utils.http.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

/**
 * @author liulei
 * @version 1.0
 */
@Slf4j
@Controller
public class RouteController {

    @Value("${oauth.login_url}")
    private String LOGIN_URL;
    @Value("${oauth.get_code_url}")
    private String GET_CODE_URL;
    @Value("${oauth.get_token_url}")
    private String GET_TOKEN_URL;
    @Value("${oauth.redirect_url}")
    private String REDIRECT_URI;
    @Value("${oauth.resource.client_id}")
    private String RS_USER_CLIENT_ID;
    @Value("${oauth.resource.client_secret}")
    private String RS_USER_CLIENT_SECRET;
    @Value("${oauth.resource.user_api}")
    private String getResourceUserAPI;

    /**
     * 请求授权码code回调页面【前后端分离的情况下，前端与后台的交互感知需要一个中间页面，否则登录状态会影响授权中心页面的跳转，前端无法感知到】
     */
    @RequestMapping("/oauth/callback")
    public String oauthCallback() {
        return "callback";
    }

    /**
     * 根据code去授权服务中心【oauth_server】获取token信息
     * 正常的/oauth/token接口返回，都只有仅仅access_token、refresh的信息，但是为了方便，最好还是在AS授权服务器实现`TokenEnhancer`增强接口
     * 返回token的同时，同样去拿到授权登录后的用户信息
     */
    @ResponseBody
    @RequestMapping("/token/{code}")
    public Map<String, Object> token(@PathVariable String code) {
        // 1.拿到code之后，通过后台构建http请求，去授权服务中心获取access_token
        MultiValueMap<String, Object> map = new LinkedMultiValueMap<>(6);
        map.add("grant_type", "authorization_code");
        map.add("code", code);
        map.add("redirect_uri", REDIRECT_URI);
        map.add("client_id", RS_USER_CLIENT_ID);
        map.add("client_secret", RS_USER_CLIENT_SECRET);
        Map<String, Object> tokenMap = HttpUtils.postSend(GET_TOKEN_URL, Map.class, map);
        log.info("根据code:{}拿到授权服务端Token信息:{}", code, tokenMap);
        // 2.拿到access_token之后，去访问授权服务中心的用户信息
        if (tokenMap.get("status") != null) {
            throw new RuntimeException(tokenMap.get("message").toString());
        }
        return tokenMap;
    }

    @RequestMapping("/registry/authorization")
    public void redirectToOAuthServer(HttpServletResponse response, String authType, String state) throws IOException {
        log.info("app接收到用户的发起的授权:{}", authType);
        // 代替前端做翻译，发起获取授权码请求
        StringBuilder builder = new StringBuilder(GET_CODE_URL);
        builder.append("?response_type=code");
        builder.append("&client_id=" + RS_USER_CLIENT_ID);
        builder.append("&redirect_uri=" + REDIRECT_URI);
        builder.append("&scope=read");
        builder.append("&state=" + state);
        response.sendRedirect(builder.toString());
    }

    /**
     * 登录授权之后，拿到token，根据开发出来的资源服务器配置，利用api获取其某个接口信息
     */
    @ResponseBody
    @RequestMapping("/resource/get")
    public JsonResult getResourceAPI(String accessToken) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add("Authorization", "Bearer " + accessToken);
        String res = HttpUtils.getSend(getResourceUserAPI, String.class, httpHeaders);
        return JsonResult.ok(res);
    }
}
